.POSIX:

#
# Special targets
#

.PHONY: \
	all \
	lint \
	check \
	clean \
	depend \
	dist \
	distcheck \
	distclean \
	install \
	install-strip \
	installdirs \
	maintainer-clean \
	man \
	mostlyclean \
	mrproper \
	quickcheck \
	quicklint \
	tags \
	tidy \
	uninstall \
	$(testscripts)

.SUFFIXES:

.SUFFIXES: .c .o .o.a .sh .gv.pdf .gv.svg 

all: sucgi


#
# Macros
#

# Build
CC = cc
CFLAGS = -O1
CPPFLAGS = -I.
AR = ar
ARFLAGS = cru
LDFLAGS =
LDLIBS =

srcs = \
	sucgi.c \
	$(libsucgisrcs) \
	$(libutilsrcs) \
	$(libmocksrcs) \
	$(testsrcs) \
	$(utilsrcs) \
	$(wrappersrcs)

hdrs = \
	$(corehdrs) \
	$(libsucgihdrs) \
	$(libutilhdrs) \
	$(libmockhdrs) \
	$(testhdrs)

objs = \
	$(libsucgiobjs) \
	$(libutilobjs) \
	$(libmockobjs)

bins = \
	sucgi \
	tests/bin/sucgi \
	$(testbins) \
	$(utilbins) \
	$(wrapperbins)

scripts = \
	configure \
	installc \
	libutil.sh \
	scripts/checkcomps \
	scripts/checkmakes \
	scripts/checkshells \
	scripts/makedepend \
	$(testscripts)


# GNU
DESTDIR = 
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
PREFIX = /usr/local
VPATH = $(srcdir)
datarootdir = $(prefix)/share
exec_prefix = $(prefix)
libexecdir = $(exec_prefix)/libexec
man8dir = $(mandir)/man8
man8ext = .8
mandir = $(datarootdir)/man
prefix = $(PREFIX)
srcdir = .

# Applications
CLANGTIDY = clang-tidy
CLANGTIDYFLAGS = --quiet
CPPCHECK = cppcheck
CPPCHECKFLAGS = \
	--quiet \
	--force \
	--language=c \
	--std=c99 \
	--library=posix \
	--library=cppcheck/c99.cfg \
	--library=cppcheck/gnuc.cfg \
	--library=cppcheck/posix.cfg \
	--library=cppcheck/bsd.cfg \
	--library=cppcheck/linux.cfg \
	--library=cppcheck/sucgi.cfg \
	--suppress-xml=cppcheck/suppress.xml \
	--inline-suppr \
	--enable=all \
	--check-level=exhaustive \
	--addon=cppcheck/cert.py \
	--addon=misra.py \
	--error-exitcode=1 \
	--cppcheck-build-dir=cppcheck/build
CSCOPE = cscope
CTAGS = ctags
DOT = dot
EGYPT = egypt
EGYPTCFLAGS = -DNDEBUG -O0 -fno-inline-functions
FLAWFINDER = flawfinder
FLAWFINDERFLAGS = --dataonly --falsepositive --error-level=1 --quiet
GPG = gpg -ab
GPGFLAGS = -q --batch --yes
PANDOC = pandoc
PANDOCFLAGS = -Mdate="$$(date +"%B %d, %Y")"
PATHCHK = pathchk
RATS = rats
RATSFLAGS = --resultsonly --quiet --warning 3
PARA = tests/utils/para
PARAFLAGS = -ci75 -j8 -t300
SHELL = /bin/sh
SHELLCHECK = shellcheck
SHELLCHECKFLAGS = -x
TAR = pax -w -s'/^/$(dist)\//' -xustar
UNTAR = tar x
UNZIP = gunzip -c
ZIP = gzip -9


# Distribution
package = sucgi
version = 0
dist = $(package)-$(version)
distar = $(dist).tgz
# TODO: Add man page
distfiles = \
	$(buildconfigs) \
	$(srcs) \
	$(hdrs) \
	$(scripts) \
	.clang-tidy \
	LICENSE.txt \
	README.md \
	config.h.tpl \
	cppcheck/bsd.cfg \
	cppcheck/c99.cfg \
	cppcheck/cert.py \
	cppcheck/gnuc.cfg \
	cppcheck/linux.cfg \
	cppcheck/posix.cfg \
	cppcheck/sucgi.cfg \
	cppcheck/suppress.xml \
	docs/build.rst \
	docs/install.md \
	docs/testing.md \
	docs/uninstall.md \
	Makefile.in

# Installation
cgidir = /usr/lib/cgi-bin
instdirs = $(DESTDIR)$(cgidir) $(DESTDIR)$(libexecdir)
instlog = install.log
webgroup = www-data

# Testing
preload = LD_PRELOAD

# Directories
dirsentinels = \
	cppcheck/build/.sentinel \
	tests/.sentinel \
	tests/bin/.sentinel \
	tests/libmock/.sentinel \
	tests/libutil/.sentinel \
	tests/utils/.sentinel

# If ./configure fails, re-run it as
# 	
# 	./configure >config.mk
#
# and then uncomment the next line:
#include config.mk


#
# Inference rules
#

.c:
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -o$@ $< $(LDLIBS)

.c.o:
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -c -o$@ $< $(LDLIBS)

.o.a:
	$(AR) $(ARFLAGS) $@ $?

.gv.svg:
	$(DOT) $(DOTFLAGS) -Tsvg -o$@ $<

.gv.pdf:
	$(DOT) $(DOTFLAGS) -Tpdf -o$@ $<


#
# Makefile
#

buildconfigs = \
	conf/devel.env \
	conf/posix.env \
	conf/prod.env \
	conf/unsafe.env

Makefile: Makefile.in $(buildconfigs)
	./config.status || [ $$? -eq 127 ]


#
# Build
#

corehdrs = attr.h config.h macros.h params.h types.h

sucgi: libsucgi.a
	# Some BSD makes need this, I cannot fathom why
	$(MAKE) -e libsucgi.a
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) \
		-o$@ $(srcdir)/sucgi.c libsucgi.a $(LDLIBS)

# libsucgi.a
libsucgisrcs = \
	env.c \
	error.c \
	groups.c \
	handler.c \
	pair.c \
	path.c \
	priv.c \
	str.c \
	user.c

libsucgihdrs = $(libsucgisrcs:.c=.h)
libsucgiobjs = $(libsucgisrcs:.c=.o)

libsucgi.a: $(libsucgiobjs)
	$(AR) $(ARFLAGS) $@ $?


#
# Installation
#

install: \
	pre-install \
	installdirs \
	$(DESTDIR)$(libexecdir)/sucgi \
	$(DESTDIR)$(cgidir)/sucgi

installdirs: $(instdirs)

uninstall: uninstallfiles uninstalldirs post-uninstall

$(DESTDIR)$(cgidir)/sucgi: $(DESTDIR)$(libexecdir)/sucgi
	ln -s $(DESTDIR)$(libexecdir)/sucgi $(DESTDIR)$(cgidir)/sucgi
	printf 'file: %s\n' $@ >>$(instlog)

$(DESTDIR)$(libexecdir)/sucgi: sucgi
	$(INSTALL_PROGRAM) -g $(webgroup) -m u=rws,g=x,o= \
		sucgi $(DESTDIR)$(libexecdir)
	printf 'file: %s\n' $@ >>$(instlog)

$(instdirs):
	$(PRE_INSTALL)
	mkdir -pm 0755 $@
	printf 'dir: %s\n' $@ >>$(instlog)

install-strip:
	$(MAKE) -e INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install

post-uninstall:
	$(POST_UNINSTALL)
	rm -f $(instlog)

pre-install:
	$(PRE_INSTALL)
	set -C && : >$(instlog)

uninstalldirs:
	$(POST_UNINSTALL)
	- sed -n 's/^dir: //p' $(instlog) | xargs -E '' rmdir -pv

uninstallfiles:
	$(NORMAL_UNINSTALL)
	sed -n 's/^file: //p' $(instlog) | xargs -E '' rm -f


#
# Distribution
#

dist: check lint shellcheck $(distar) $(distar).asc

distcheck: dist
	rm -rf $(dist)
	$(UNZIP) $(distar) | $(UNTAR)
	cp -p $(dist)/config.h.tpl $(dist)/config.h
	cd $(dist) && ./configure && $(MAKE) dist
	rm -rf $(dist)

$(distar): depend $(distfiles)
	$(PATHCHK) $(PATHCHKFLAGS) -Pp $(distfiles)
	$(TAR) $(distfiles) | $(ZIP) >$@

$(distar).asc: $(dist).tgz
	$(GPG) $(GPGFLAGS) $(distar)



#
# Tags
#

TAGS: tags

tags: $(srcs)
	$(CTAGS) $(CTAGSFLAGS) $(srcs)


#
# Documentation
#

man: sucgi$(man8ext)

docs/callgraph.pdf: docs/callgraph.gv

docs/callgraph.svg: docs/callgraph.gv

docs/callgraph.gv: sucgi.c $(libsucgisrcs)
	$(MAKE) -e CFLAGS="-fdump-rtl-expand $(EGYPTCFLAGS)" clean sucgi
	$(EGYPT) --callees main $(EGYPTFLAGS) *.expand >$@
	find . -name '*.expand' -exec rm -f '{}' +


#
# Cleanup
#

maintainer-clean: distclean
	@echo '$@ is for maintainers only!'
	@echo 'It deletes files that cannot be built with standard tools'
	rm -f docs/callgraph.* $(deps)

distclean: mrproper
	rm -f Makefile config.status

mrproper: clean
	rm -rf $(package)-* cppcheck/build 
	rm -f cscope.out tags
	find . '(' \
		-name '*.dump' -o \
		-name '*.expand' -o \
		-name '*.gc*' -o \
		-name '*.info' \
	')' -exec rm -f '{}' +
	- find . -type d -links 2 | sed 's/^\.\///' | xargs -E '' rmdir -p

clean: mostlyclean
	rm -f $(distar) $(distar).asc
	find . -name '*.sentinel' -exec rm '{}' +

mostlyclean: tidy
	rm -f $(bins) $(objs) libsucgi.a tests/libutil.a tests/libmock.so

tidy:
	find . -name 'tmp-*' -exec rm -rf '{}' +
	find . '(' -name '*.bak' -o -name '*.log' ')' -exec rm -f '{}' +


#
# Utilities
#

utilsrcs = \
	tests/utils/badenv.c \
	tests/utils/badexec.c \
	tests/utils/para.c \
	tests/utils/runas.c \
	tests/utils/uids.c

utilbins = $(utilsrcs:.c=)

$(utilbins):
	$(CC) -DNDEBUG -O1 -o$@ -o$@ $(srcdir)/$@.c


#
# Tests
#

# Unit tests
testsrcs = $(macrotestsrcs) $(functestsrcs) 
testhdrs = tests/types.h
testbins = $(testsrcs:.c=)

macrotestsrcs = \
	tests/ISSIGNED.c \
	tests/NELEMS.c \
	tests/MAXSVAL.c

macrotestbins = $(macrotestsrcs:.c=)

functestsrcs = \
	tests/env_is_name.c \
	tests/env_restore.c \
	tests/env_set_many.c \
	tests/handler_find.c \
	tests/groups_comp.c \
	tests/groups_find.c \
	tests/groups_sub.c \
	tests/pair_find.c \
	tests/path_real.c \
	tests/path_suffix.c \
	tests/path_is_sub.c \
	tests/priv_drop.c \
	tests/priv_suspend.c \
	tests/str_split.c \
	tests/user_exp.c

functestbins = $(functestsrcs:.c=)

$(functestbins):
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) \
		-o$@ $(srcdir)/$@.c libsucgi.a tests/libutil.a $(LDLIBS)

$(macrotestbins): tests/libutil.a
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) \
		-o$@ $(srcdir)/$@.c tests/libutil.a $(LDLIBS)

# tests/libutil.a
libutilsrcs = \
	tests/libutil/abort.c \
	tests/libutil/array_find.c \
	tests/libutil/array_eq.c \
	tests/libutil/array_is_sub.c \
	tests/libutil/dir_tree_rm.c \
	tests/libutil/dir_walk.c \
	tests/libutil/path_gen.c \
	tests/libutil/path_join.c \
	tests/libutil/path_split.c \
	tests/libutil/path_walk.c \
	tests/libutil/sigs_abort.c \
	tests/libutil/sigs_term.c \
	tests/libutil/sigs_action.c \
	tests/libutil/sigs_handle.c \
	tests/libutil/sigs_reraise.c \
	tests/libutil/sigs_retry_i.c \
	tests/libutil/sigs_retry_p.c \
	tests/libutil/sigs_trap.c \
	tests/libutil/str_cmp_ptrs.c \
	tests/libutil/tmpdir_make.c \
	tests/libutil/user_get_grp.c \
	tests/libutil/user_get_reg.c

libutilhdrs = \
	tests/libutil/sigs.h \
	tests/libutil/path.h \
	tests/libutil/types.h \
	tests/libutil/tmpdir.h \
	tests/libutil/user.h \
	tests/libutil/array.h \
	tests/libutil/str.h \
	tests/libutil/dir.h \
	tests/libutil/abort.h

libutilobjs = $(libutilsrcs:.c=.o)

tests/libutil.a: $(libutilobjs)
	$(AR) $(ARFLAGS) $@ $?

$(libutilobjs):

# tests/libmock.so
libmocksrcs = tests/libmock/mockstd.c
libmockhdrs = $(libmocksrcs:.c=.h)
libmockobjs = $(libmocksrcs:.c=.o)

$(libmockobjs):
	$(CC) -fPIE -c -o$@ $(srcdir)/$(@:.o=.c) $(LDLIBS)

tests/libmock.so: $(libmockobjs)
	$(CC) -shared -o$@ $(libmockobjs) $(LDLIBS)

# Wrappers for scripted tests
wrappersrcs = tests/bin/BUG.c tests/bin/error.c
wrapperbins = $(wrappersrcs:.c=)
wrapperflags = -DTESTING

tests/bin/BUG: libsucgi.a(error.o)

$(wrapperbins):
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $(wrapperflags) \
		-o$@ $(srcdir)/$@.c libsucgi.a $(LDLIBS)

tests/bin/sucgi: libsucgi.a
	$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $(wrapperflags) \
		-o$@ $(srcdir)/sucgi.c libsucgi.a $(LDLIBS)

# Scripted tests
testscripts = \
	$(srcdir)/tests/sucgi \
	$(srcdir)/tests/BUG \
	$(srcdir)/tests/error

# Execution
checks = $(testscripts) $(testbins)
environ = PATH="$$PATH:tests/bin:tests/utils"

check: $(checks) $(wrapperbins) $(utilbins) tests/bin/sucgi
	$(PARA) $(PARAFLAGS) $(environ) $(checks)

quickcheck: $(checks) $(utilbins)
	$(PARA) $(PARAFLAGS) $(environ) $(testbins)

mockcheck: $(checks) $(wrapperbins) $(utilbins) tests/bin/sucgi tests/libmock.so
	$(PARA) $(PARAFLAGS) $(environ) $(preload)=tests/libmock.so $(checks)

checks: $(testbins)


#
# Linters
#

# TODO: Add valgrind
lint: cppcheck/build/.sentinel quicklint
	$(CLANGTIDY) $(CLANGTIDYFLAGS) $(srcs) -- $(CPPFLAGS) || [ $$? -eq 127 ]
	$(CPPCHECK) $(CPPCHECKFLAGS) $(CPPFLAGS) $(srcs) || [ $$? -eq 127 ]

quicklint:
	$(FLAWFINDER) $(FLAWFINDERFLAGS) $(srcs) || [ $$? -eq 127 ]
	$(RATS) $(RATSFLAGS) $(srcs) || [ $$? -eq 127 ]

shellcheck:
	$(SHELLCHECK) $(SHELLCHECKFLAGS) $(scripts) || [ $$? -eq 127 ]


#
# Directories
#

$(dirsentinels):
	dirname $@ | xargs mkdir -p
	touch $@


#
# Dependencies
#

deps = $(bindeps) $(objdeps) sucgi.d tests/bin/sucgi.d
libs = libsucgi.a tests/libutil.a
bindeps = $(binsrcs:.c=.d)
objdeps = $(objsrcs:.c=.d)
binsrcs = sucgi.c $(testsrcs) $(utilsrcs) $(wrappersrcs)
objsrcs = $(libsucgisrcs) $(libmocksrcs) $(libutilsrcs)

depend: $(deps)
	sed -i.bak '/^# Auto-generated dependencies$$/ q' Makefile.in
	cat $(deps) >>Makefile.in

$(objdeps): $(libs)
	scripts/makedepend -o$@ -t"$(@:.d=.o) $@" $(@:.d=.o) $(libs)

$(bindeps): $(libs)
	scripts/makedepend -o$@ -t"$(@:.d=) $@" $(@:.d=) $(libs)

tests/bin/sucgi.d: $(libs)
	scripts/makedepend -o$@ -t"$(@:.d=) $@" sucgi $(libs)

# Auto-generated dependencies
sucgi sucgi.d: \
	sucgi.c \
	attr.h \
	config.h \
	env.h \
	error.h \
	handler.h \
	macros.h \
	params.h \
	path.h \
	priv.h \
	str.h \
	types.h \
	user.h \
	libsucgi.a(env.o) \
	libsucgi.a(error.o) \
	libsucgi.a(handler.o) \
	libsucgi.a(pair.o) \
	libsucgi.a(path.o) \
	libsucgi.a(priv.o) \
	libsucgi.a(str.o) \
	libsucgi.a(user.o)

tests/ISSIGNED tests/ISSIGNED.d: \
	tests/ISSIGNED.c \
	macros.h \
	tests/libutil/types.h \
	tests/types.h \
	tests/.sentinel

tests/NELEMS tests/NELEMS.d: \
	tests/NELEMS.c \
	macros.h \
	tests/libutil/abort.h \
	tests/libutil/types.h \
	tests/types.h \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/MAXSVAL tests/MAXSVAL.d: \
	tests/MAXSVAL.c \
	macros.h \
	tests/libutil/abort.h \
	tests/libutil/types.h \
	tests/types.h \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/env_is_name tests/env_is_name.d: \
	tests/env_is_name.c \
	attr.h \
	config.h \
	env.h \
	macros.h \
	params.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(env.o) \
	libsucgi.a(str.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/env_restore tests/env_restore.d: \
	tests/env_restore.c \
	attr.h \
	config.h \
	env.h \
	macros.h \
	params.h \
	str.h \
	tests/libutil/abort.h \
	tests/libutil/array.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(env.o) \
	libsucgi.a(str.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(array_eq.o) \
	tests/libutil.a(array_find.o) \
	tests/libutil.a(array_is_sub.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/env_set_many tests/env_set_many.d: \
	tests/env_set_many.c \
	attr.h \
	config.h \
	env.h \
	macros.h \
	params.h \
	str.h \
	tests/libutil/abort.h \
	tests/libutil/array.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(env.o) \
	libsucgi.a(str.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(array_eq.o) \
	tests/libutil.a(array_find.o) \
	tests/libutil.a(array_is_sub.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/handler_find tests/handler_find.d: \
	tests/handler_find.c \
	attr.h \
	config.h \
	handler.h \
	macros.h \
	params.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(handler.o) \
	libsucgi.a(pair.o) \
	libsucgi.a(path.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/groups_comp tests/groups_comp.d: \
	tests/groups_comp.c \
	attr.h \
	config.h \
	env.h \
	groups.h \
	macros.h \
	params.h \
	tests/libutil/abort.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(groups.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/groups_find tests/groups_find.d: \
	tests/groups_find.c \
	attr.h \
	config.h \
	env.h \
	groups.h \
	macros.h \
	params.h \
	tests/libutil/abort.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(groups.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/groups_sub tests/groups_sub.d: \
	tests/groups_sub.c \
	attr.h \
	config.h \
	env.h \
	groups.h \
	macros.h \
	params.h \
	tests/libutil/abort.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(groups.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/pair_find tests/pair_find.d: \
	tests/pair_find.c \
	attr.h \
	config.h \
	macros.h \
	pair.h \
	params.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(pair.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/path_real tests/path_real.d: \
	tests/path_real.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	path.h \
	tests/libutil/abort.h \
	tests/libutil/array.h \
	tests/libutil/dir.h \
	tests/libutil/path.h \
	tests/libutil/sigs.h \
	tests/libutil/tmpdir.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(path.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(array_find.o) \
	tests/libutil.a(dir_tree_rm.o) \
	tests/libutil.a(dir_walk.o) \
	tests/libutil.a(path_gen.o) \
	tests/libutil.a(path_join.o) \
	tests/libutil.a(path_split.o) \
	tests/libutil.a(path_walk.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_reraise.o) \
	tests/libutil.a(sigs_retry_i.o) \
	tests/libutil.a(sigs_retry_p.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/libutil.a(tmpdir_make.o) \
	tests/.sentinel

tests/path_suffix tests/path_suffix.d: \
	tests/path_suffix.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	path.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(path.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/path_is_sub tests/path_is_sub.d: \
	tests/path_is_sub.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	path.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(path.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/priv_drop tests/priv_drop.d: \
	tests/priv_drop.c \
	attr.h \
	config.h \
	groups.h \
	macros.h \
	params.h \
	priv.h \
	tests/libutil/array.h \
	tests/libutil/types.h \
	tests/libutil/user.h \
	tests/types.h \
	types.h \
	libsucgi.a(priv.o) \
	tests/libutil.a(array_eq.o) \
	tests/libutil.a(array_find.o) \
	tests/libutil.a(array_is_sub.o) \
	tests/libutil.a(user_get_grp.o) \
	tests/libutil.a(user_get_reg.o) \
	tests/.sentinel

tests/priv_suspend tests/priv_suspend.d: \
	tests/priv_suspend.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	priv.h \
	tests/libutil/abort.h \
	tests/libutil/types.h \
	tests/libutil/user.h \
	tests/types.h \
	types.h \
	libsucgi.a(priv.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/libutil.a(user_get_grp.o) \
	tests/libutil.a(user_get_reg.o) \
	tests/.sentinel

tests/str_split tests/str_split.d: \
	tests/str_split.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	str.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	libsucgi.a(str.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/user_exp tests/user_exp.d: \
	tests/user_exp.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	str.h \
	tests/libutil/abort.h \
	tests/libutil/str.h \
	tests/libutil/types.h \
	tests/types.h \
	types.h \
	user.h \
	libsucgi.a(user.o) \
	tests/libutil.a(abort.o) \
	tests/libutil.a(sigs_action.o) \
	tests/libutil.a(sigs_handle.o) \
	tests/libutil.a(sigs_trap.o) \
	tests/.sentinel

tests/utils/badenv tests/utils/badenv.d: \
	tests/utils/badenv.c \
	tests/utils/.sentinel

tests/utils/badexec tests/utils/badexec.d: \
	tests/utils/badexec.c \
	tests/utils/.sentinel

tests/utils/para tests/utils/para.d: \
	tests/utils/para.c \
	tests/utils/.sentinel

tests/utils/runas tests/utils/runas.d: \
	tests/utils/runas.c \
	tests/utils/.sentinel

tests/utils/uids tests/utils/uids.d: \
	tests/utils/uids.c \
	tests/utils/.sentinel

tests/bin/BUG tests/bin/BUG.d: \
	tests/bin/BUG.c \
	attr.h \
	error.h \
	macros.h \
	tests/bin/.sentinel

tests/bin/error tests/bin/error.d: \
	tests/bin/error.c \
	attr.h \
	error.h \
	libsucgi.a(error.o) \
	tests/bin/.sentinel

env.o env.d: \
	env.c \
	attr.h \
	config.h \
	env.h \
	params.h \
	str.h \
	types.h

error.o error.d: \
	error.c \
	attr.h \
	config.h \
	error.h \
	params.h

groups.o groups.d: \
	groups.c \
	attr.h \
	config.h \
	groups.h \
	macros.h \
	params.h \
	types.h

handler.o handler.d: \
	handler.c \
	attr.h \
	config.h \
	handler.h \
	pair.h \
	params.h \
	path.h \
	types.h

pair.o pair.d: \
	pair.c \
	attr.h \
	config.h \
	pair.h \
	params.h \
	types.h

path.o path.d: \
	path.c \
	attr.h \
	config.h \
	params.h \
	path.h \
	str.h \
	types.h

priv.o priv.d: \
	priv.c \
	attr.h \
	config.h \
	error.h \
	groups.h \
	macros.h \
	params.h \
	priv.h \
	types.h

str.o str.d: \
	str.c \
	attr.h \
	config.h \
	params.h \
	str.h \
	types.h

user.o user.d: \
	user.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	types.h \
	user.h

tests/libmock/mockstd.o tests/libmock/mockstd.d: \
	tests/libmock/mockstd.c \
	attr.h \
	config.h \
	macros.h \
	params.h \
	tests/libmock/mockstd.h \
	tests/libmock/.sentinel

tests/libutil/abort.o tests/libutil/abort.d: \
	tests/libutil/abort.c \
	attr.h \
	tests/libutil/abort.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/array_find.o tests/libutil/array_find.d: \
	tests/libutil/array_find.c \
	attr.h \
	tests/libutil/array.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/array_eq.o tests/libutil/array_eq.d: \
	tests/libutil/array_eq.c \
	attr.h \
	tests/libutil/array.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/array_is_sub.o tests/libutil/array_is_sub.d: \
	tests/libutil/array_is_sub.c \
	attr.h \
	tests/libutil/array.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/dir_tree_rm.o tests/libutil/dir_tree_rm.d: \
	tests/libutil/dir_tree_rm.c \
	attr.h \
	tests/libutil/dir.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/dir_walk.o tests/libutil/dir_walk.d: \
	tests/libutil/dir_walk.c \
	attr.h \
	tests/libutil/dir.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/path_gen.o tests/libutil/path_gen.d: \
	tests/libutil/path_gen.c \
	attr.h \
	tests/libutil/path.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/path_join.o tests/libutil/path_join.d: \
	tests/libutil/path_join.c \
	attr.h \
	tests/libutil/path.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/path_split.o tests/libutil/path_split.d: \
	tests/libutil/path_split.c \
	attr.h \
	tests/libutil/path.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/path_walk.o tests/libutil/path_walk.d: \
	tests/libutil/path_walk.c \
	attr.h \
	tests/libutil/path.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_abort.o tests/libutil/sigs_abort.d: \
	tests/libutil/sigs_abort.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_term.o tests/libutil/sigs_term.d: \
	tests/libutil/sigs_term.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_action.o tests/libutil/sigs_action.d: \
	tests/libutil/sigs_action.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_handle.o tests/libutil/sigs_handle.d: \
	tests/libutil/sigs_handle.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_reraise.o tests/libutil/sigs_reraise.d: \
	tests/libutil/sigs_reraise.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_retry_i.o tests/libutil/sigs_retry_i.d: \
	tests/libutil/sigs_retry_i.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_retry_p.o tests/libutil/sigs_retry_p.d: \
	tests/libutil/sigs_retry_p.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/sigs_trap.o tests/libutil/sigs_trap.d: \
	tests/libutil/sigs_trap.c \
	attr.h \
	tests/libutil/sigs.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/str_cmp_ptrs.o tests/libutil/str_cmp_ptrs.d: \
	tests/libutil/str_cmp_ptrs.c \
	attr.h \
	tests/libutil/str.h \
	tests/libutil/.sentinel

tests/libutil/tmpdir_make.o tests/libutil/tmpdir_make.d: \
	tests/libutil/tmpdir_make.c \
	attr.h \
	config.h \
	params.h \
	tests/libutil/path.h \
	tests/libutil/tmpdir.h \
	tests/libutil/types.h \
	tests/libutil/.sentinel

tests/libutil/user_get_grp.o tests/libutil/user_get_grp.d: \
	tests/libutil/user_get_grp.c \
	attr.h \
	config.h \
	params.h \
	tests/libutil/types.h \
	tests/libutil/user.h \
	tests/libutil/.sentinel

tests/libutil/user_get_reg.o tests/libutil/user_get_reg.d: \
	tests/libutil/user_get_reg.c \
	attr.h \
	tests/libutil/types.h \
	tests/libutil/user.h \
	tests/libutil/.sentinel

sucgi sucgi.d: \
	sucgi.c \
	attr.h \
	config.h \
	env.h \
	error.h \
	handler.h \
	macros.h \
	params.h \
	path.h \
	priv.h \
	str.h \
	types.h \
	user.h \
	libsucgi.a(env.o) \
	libsucgi.a(error.o) \
	libsucgi.a(handler.o) \
	libsucgi.a(pair.o) \
	libsucgi.a(path.o) \
	libsucgi.a(priv.o) \
	libsucgi.a(str.o) \
	libsucgi.a(user.o)

tests/bin/sucgi tests/bin/sucgi.d: \
	sucgi.c \
	attr.h \
	config.h \
	env.h \
	error.h \
	handler.h \
	macros.h \
	params.h \
	path.h \
	priv.h \
	str.h \
	types.h \
	user.h \
	libsucgi.a(env.o) \
	libsucgi.a(error.o) \
	libsucgi.a(handler.o) \
	libsucgi.a(pair.o) \
	libsucgi.a(path.o) \
	libsucgi.a(priv.o) \
	libsucgi.a(str.o) \
	libsucgi.a(user.o)

